package com.parleys.android.client.ui;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.BaseColumns;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.parleys.android.client.R;
import com.parleys.android.client.provider.ParleysContract.Channels;
import com.parleys.android.client.provider.ParleysContract.Spaces;
import com.parleys.android.client.service.ParleysService;
import com.parleys.android.client.service.ParleysServiceHelper;
import com.parleys.android.client.util.DetachableResultReceiver;
import com.parleys.android.client.util.DetachableResultReceiver.Receiver;
import com.parleys.android.client.util.NotifyingAsyncQueryHandler;
import com.parleys.android.client.util.NotifyingAsyncQueryHandler.AsyncQueryListener;
import com.parleys.android.client.util.ParleysUriUtils;
import com.parleys.android.client.util.UIUtils;

public class ChannelsActivity extends ListActivity implements AsyncQueryListener, Receiver {

	private static final String TAG = "ChannelsActivity";
	
    private State mState;

    private static ParleysServiceHelper parleysServiceHelper = ParleysServiceHelper.getInstance();
    private Uri mChannelsUri;
	private NotifyingAsyncQueryHandler mHandler;
    private ChannelsAdapter mAdapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.activity_channels);

        mState = (State) getLastNonConfigurationInstance();
        final boolean previousState = mState != null;

        mChannelsUri = this.getIntent().getData();

        mAdapter = new ChannelsAdapter(this);
        setListAdapter(mAdapter);

        mHandler = new NotifyingAsyncQueryHandler(this, this);
        startQuery();

        if (previousState) {
            mState.mReceiver.setReceiver(this);
            updateRefreshStatus();
        } else {
            mState = new State();
            mState.mReceiver.setReceiver(this);
            parleysServiceHelper.getChannels(this, Spaces.getSpaceId(mChannelsUri), mState.mReceiver);
        }
	}

	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();
		final Window window = getWindow();
		window.setFormat(PixelFormat.RGBA_8888);
	}
	
	@Override
    public Object onRetainNonConfigurationInstance() {
        mState.mReceiver.clearReceiver();
        return mState;
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

	public void onQueryComplete(int token, Object cookie, Cursor cursor) {
		cursor.setNotificationUri(getContentResolver(), mChannelsUri);
		startManagingCursor(cursor);
		mAdapter.changeCursor(cursor);
	}

	public void onHomeClick(View v) {
		UIUtils.goHome(this);
	}
	
    @Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
        final Cursor cursor = (Cursor) mAdapter.getItem(position);
        final int channelId = cursor.getInt(ChannelsQuery.CHANNEL_ID);
        final Uri presentationsUri = Channels.buildPresentationsDirUri(channelId);
        final Intent intent = new Intent(Intent.ACTION_VIEW, presentationsUri);
        intent.putExtra(Intent.EXTRA_TITLE, cursor.getString(ChannelsQuery.NAME));
        startActivity(intent);
	}

	private void startQuery() {
    	mHandler.cancelOperation(ChannelsQuery.TOKEN);
        mHandler.startQuery(ChannelsQuery.TOKEN, null, mChannelsUri, ChannelsQuery.PROJECTION, null, null, ChannelsQuery.SORT);
    }
    
    private void updateRefreshStatus() {
        findViewById(R.id.refresh_channels_separator).setVisibility(mState.mSyncing ? View.VISIBLE : View.GONE);
        findViewById(R.id.refresh_channels_progress).setVisibility(mState.mSyncing ? View.VISIBLE : View.GONE);
    }
    
    /** {@inheritDoc} */
    public void onReceiveResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
            case ParleysService.STATUS_RUNNING: {
                mState.mSyncing = true;
                updateRefreshStatus();
                break;
            }
            case ParleysService.STATUS_FINISHED: {
                mState.mSyncing = false;
                updateRefreshStatus();
                break;
            }
            case ParleysService.STATUS_ERROR: {
                mState.mSyncing = false;
                updateRefreshStatus();
                break;
            }
        }
    }

    public static final class ChannelsItemViews {
    	ImageView thumbnailView;
        TextView nameView;
    }

    private class ChannelsAdapter extends CursorAdapter {
    	
		public ChannelsAdapter(Context context) {
			super(context, null);
		}

	    protected void findAndCacheViews(View view) {
	    	ChannelsItemViews views = new ChannelsItemViews();
	    	views.thumbnailView = (ImageView) view.findViewById(R.id.channels_thumbnail);
	        views.nameView = (TextView) view.findViewById(R.id.channels_name);
	        view.setTag(views);
	    }

	    @Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View v = getLayoutInflater().inflate(R.layout.list_item_channels, parent, false);
            findAndCacheViews(v);
            return v;
		}
    	
		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			ChannelsItemViews views = (ChannelsItemViews) view.getTag();
			
			final String channelId = cursor.getString(ChannelsQuery.CHANNEL_ID);
			final String name = cursor.getString(ChannelsQuery.NAME);
			final String thumbnailUrl = cursor.isNull(ChannelsQuery.THUMBNAIL_URL) ? null : ParleysUriUtils.buildChannelThumbnailUri(channelId, cursor.getString(ChannelsQuery.THUMBNAIL_URL));
			
            views.nameView.setText(name);
            
	        parleysServiceHelper.downloadImage(thumbnailUrl, views.thumbnailView);
		}

    }
    
    private static class State {
        public DetachableResultReceiver mReceiver;
        public boolean mSyncing = false;

        private State() {
            mReceiver = new DetachableResultReceiver(new Handler());
        }

    }

    private interface ChannelsQuery {
    	int TOKEN = 0x01;
    	
        String[] PROJECTION = {
                BaseColumns._ID,
                Channels.CHANNEL_ID,
                Channels.NAME,
                Channels.DESCRIPTION,
                Channels.THUMBNAIL_URL,
        };
        
        String SORT = Channels.DEFAULT_SORT;

        int _ID 				= 0;
        int CHANNEL_ID 			= 1;
        int NAME				= 2;
        int DESCRIPTION			= 3;
	    int THUMBNAIL_URL		= 4;			
    }
}
